/* 
 * File:   pic24fv32ka302.h
 * Author: Julian Sanin
 *
 * Created on 23/02/2014, 09:04
 *
 * Peripheral Hardware Abstraction.
 * 
 */

#ifndef PIC24FV32KA302_H
#define	PIC24FV32KA302_H

#include <xc.h>
#include <stdint.h>
#include <stddef.h>

#ifdef	__cplusplus
extern "C" {
#endif

/** Disables interrupts for up to 16383 clock cycles. */
#define _disable_interrupts() __asm__ volatile("DISI #0x3FFF")

/** Reenables interrupts. */
#define _enable_interrupts() (DISICNT = 0)

/** Null Peripheral base pointer. */
#define MODULE_NULL NULL

/******************************************************************************
 * Timer Peripheral Access Abstraction Layer.
 ******************************************************************************/

/** 16 Bit Timer Peripheral Register Map. */
typedef volatile struct T16registers {
    /** Type A Timer Register. */
    uint16_t TMRA;
    /** Type A Period Register. */
    uint16_t PRA;
    /** Type A Time Base Control Register. */
    union CONAregister {
        uint16_t word;
        struct CONAbits {
            unsigned :1;
            /** Timer Clock Source Select bit. */
            unsigned TCS:1;
            /** Timer External Clock Input Synchronization Select bit. */
            unsigned TSYNC:1;
            unsigned :1;
            /** Timer Input Clock Prescale Select bits. */
            unsigned TCKPS:2;
            /** Timer Gated Time Accumulation Enable bit. */
            unsigned TGATE:1;
            unsigned :1;
            /** Timer Extended Clock Select bits. */
            unsigned TECS:2;
            unsigned :3;
            /** Stop Module in Idle Mode bit. */
            unsigned TSIDL:1;
            unsigned :1;
            /** Timer On bit. */
            unsigned TON:1;
        } bits;
    } CON;
} T16registers;

/** 32 Bit Combined Timer Peripheral Register Map. */
typedef volatile struct T32registers {
    /** Type B Timer Register. */
    uint16_t TMRB;
    /** Type C Holding Register (in 32-bit mode). */
    uint16_t TMRCHLD;
    /** Type C Timer Register. */
    uint16_t TMRC;
    /** Type B Period Register. */
    uint16_t PRB;
    /** Type C Period Register. */
    uint16_t PRC;
    union CONBregister {
        uint16_t word;
        /** Type B Time Base Control Register. */
        struct CONBbits {
            unsigned :1;
            /** Timer Clock Source Select bit. */
            unsigned TCS:1;
            unsigned :1;
            /** 32-Bit Timer Mode Select bit. */
            unsigned T32:1;
            /** Timer Input Clock Prescale Select bits. */
            unsigned TCKPS:2;
            /** Timer Gated Time Accumulation Enable bit. */
            unsigned TGATE:1;
            unsigned :6;
            /** Stop Module in Idle Mode bit. */
            unsigned TSIDL:1;
            unsigned :1;
            /** Timer On bit. */
            unsigned TON:1;
        } bits;
    } CONB;
    /** Type C Time Base Control Register. */
    union CONCregister {
        uint16_t word;
        struct CONCbits {
            unsigned :1;
            /** Timer Clock Source Select bit. */
            unsigned TCS:1;
            unsigned :2;
            /** Timer Input Clock Prescale Select bits. */
            unsigned TCKPS:2;
            /** Timer Gated Time Accumulation Enable bit. */
            unsigned TGATE:1;
            unsigned :6;
            /** Stop Module in Idle Mode bit. */
            unsigned TSIDL:1;
            unsigned :1;
            /** Timer On bit. */
            unsigned TON:1;
        } bits;
    } CONC;
} T32registers;

/** Peripheral Timer 1 base pointer. */
#define MODULE_T1 ((T16registers *)&TMR1)

/** Peripheral combined Timer 2 and Timer 3 base pointer. */
#define MODULE_T23 ((T32registers *)&TMR2)

/** Peripheral combined Timer 4 and Timer 5 base pointer. */
#define MODULE_T45 ((T32registers *)&TMR4)

/******************************************************************************
 * Output Compare Peripheral Access Abstraction Layer.
 ******************************************************************************/

/** Output Compare Peripheral Register Map. */
typedef volatile struct OCregisters {
    /** Output Compare Control Register 1 (Offset 0x0). */
    union CON1register {
        uint16_t word;
        struct CON1bits {
            /** Output Compare Mode Select. */
            unsigned OCM:3;
            /** Trigger Status Mode Select. */
            unsigned TRIGMODE:1;
            /** PWM Fault 0 Condition Status Flag. */
            unsigned OCFLT0:1;
            /** PWM Fault 1 Condition Status Flag (alt. fault mapping). */
            unsigned OCFLT1:1;
            /** PWM Fault 2 Condition Status Flag (alt. fault mapping). */
            unsigned OCFLT2:1;
            /** Fault 0 Input Enable (OCFA pin). */
            unsigned ENFLT0:1;
            /** Fault 1 Input Enable (alt. fault mapping). */
            unsigned ENFLT1:1;
            /** Fault 2 Input Enable (alt. fault mapping). */
            unsigned ENFLT2:1;
            /** Output Compare Clock Select. */
            unsigned OCTSEL:3;
            /** Stop Module in Idle Mode. */
            unsigned OCSIDL:1;
        } bits;
    } CON1;
    /** Output Compare Control Register 2 (Offset 0x2). */
    union CON2register {
        uint16_t word;
        struct CON2bits {
            /** Trigger/Synchronization Source Selection. */
            unsigned SYNCSEL:5;
            /** OC Output Pin Direction Select. */
            unsigned OCTRIS:1;
            /** Timer Trigger Status. */
            unsigned TRIGSTAT:1;
            /** OCx Trigger/Sync Select. */
            unsigned OCTRIG:1;
            /** Cascade Two OC Module Enable (32-bit operation). */
            unsigned OC32:1;
            /** PWM Duty Cycle Least Significant Bits. */
            unsigned DCB:2;
            unsigned :1;
            /** OCMP Invert Bit. */
            unsigned OCMPINV:1;
            /** Fault Output State Select Enable. */
            unsigned FLTTRIEN:1;
            /** Fault Out Bit. */
            unsigned FLTOUT:1;
            /** Fault Mode Select. */
            unsigned FLTMD:1;
        } bits;
    } CON2;
    /** Secondary Compare Register (Offset 0x4). */
    uint16_t RS;
    /** Compare Register (Offset 0x6). */
    uint16_t R;
    /** Timer Register (Offset 0x8). */
    uint16_t TMR;
} OCregisters;

/** Peripheral OC1 base pointer. */
#define MODULE_OC1 ((OCregisters *)&OC1CON1)

/** Peripheral OC2 base pointer. */
#define MODULE_OC2 ((OCregisters *)&OC2CON1)

/** Peripheral OC3 base pointer. */
#define MODULE_OC3 ((OCregisters *)&OC3CON1)

/******************************************************************************
 * I2C Peripheral Access Abstraction Layer.
 ******************************************************************************/

/** I2C Peripheral Register Map. */
typedef volatile struct I2Cregisters {
    /** I2C Receive Register (Offset 0x0). */
    uint16_t RCV;
    /** I2C Transmit Register (Offset 0x2). */
    uint16_t TRN;
    /** I2C Baudrate Register (Offset 0x4). */
    uint16_t BRG;
    /** I2C Control Register (Offset 0x6). */
    union CONregister {
        uint16_t word;
        struct CONbits {
            /** Master Start Enable. */
            unsigned SEN:1;
            /** Master Repeated Start Enable. */
            unsigned RSEN:1;
            /** Master Stop Enable. */
            unsigned PEN:1;
            /** Master Receive Enable. */
            unsigned RCEN:1;
            /** Master Acknowledge Enable. */
            unsigned ACKEN:1;
            /** Master Acknowledge Data Bit. */
            unsigned ACKDT:1;
            /** SCL Clock Stretch Enable. */
            unsigned STREN:1;
            /** General Call Enable. */
            unsigned GCEN:1;
            /** SMBus Input Levels Enable. */
            unsigned SMEN:1;
            /** Disable Slew Rate Control. */
            unsigned DISSLW:1;
            /** 10-Bit Slave Address Enable. */
            unsigned A10M:1;
            /** Intelligent Peripheral Management Interface Enable. */
            unsigned IPMIEN:1;
            /** SCL Release Control. */
            unsigned SCLREL:1;
            /** Stop Module in Idle Mode. */
            unsigned I2CSIDL:1;
            unsigned :1;
            /** I2C Enable. */
            unsigned I2CEN:1;
        } bits;
    } CON;
    /** I2C Status Register (Offset 0x8). */
    union STATregister {
        uint16_t word;
        struct STATbits {
            /** Transmit Buffer Full Flag. */
            unsigned TBF:1;
            /** Receive Buffer Full Flag. */
            unsigned RBF:1;
            /** Read/Write Information Flag (in Slave Mode). */
            unsigned R_W:1;
            /** Start Bit Detect Flag. */
            unsigned S:1;
            /** Stop Bit Detect Flag. */
            unsigned P:1;
            /** Data/Address Received Flag (in Slave Mode). */
            unsigned D_A:1;
            /** Receive Overflow Flag. */
            unsigned I2COV:1;
            /** Write Collision Detect Flag. */
            unsigned IWCOL:1;
            /** 10-Bit Address Match Status Flag. */
            unsigned ADD10:1;
            /** General Call Status Flag. */
            unsigned GCSTAT:1;
            /** Master Bus Collision Detect Bit. */
            unsigned BCL:1;
            unsigned :3;
            /** Transmit Status Flag. */
            unsigned TRSTAT:1;
            /** Acknowledge Status Bit Flag. */
            unsigned ACKSTAT:1;
        } bits;
    } STAT;
    /** I2C Address Register (Offset 0xA). */
    uint16_t ADD;
    /** I2C Mask Register (Offset 0xC). */
    uint16_t MSK;
} I2Cregisters;

/** Peripheral I2C1 base pointer. */
#define MODULE_I2C1 ((I2Cregisters *)&I2C1RCV)

/** Peripheral I2C2 base pointer. */
#define MODULE_I2C2 ((I2Cregisters *)&I2C2RCV)

/******************************************************************************
 * ADC Peripheral Access Abstraction Layer.
 ******************************************************************************/

/** ADC Peripheral Register Map. */
typedef volatile struct ADCregisters {
    uint16_t BUF0;
    uint16_t BUF1;
    uint16_t BUF2;
    uint16_t BUF3;
    uint16_t BUF4;
    uint16_t BUF5;
    uint16_t BUF6;
    uint16_t BUF7;
    uint16_t BUF8;
    uint16_t BUF9;
    uint16_t BUF10;
    uint16_t BUF11;
    uint16_t BUF12;
    uint16_t BUF13;
    uint16_t BUF14;
    uint16_t BUF15;
    uint16_t BUF16;
    uint16_t BUF17;
    /**/
    uint16_t CON1;
    uint16_t CON2;
    uint16_t CON3;
    uint16_t CHS;
    uint16_t CSSH;
    uint16_t CSSL;
    uint16_t CON5;
    uint16_t CHITH;
    uint16_t CHITL;
} ADCregisters;

/** Peripheral ADC1 base pointer. */
#define MODULE_ADC1 ((ADCregisters *)&ADC1BUF0)

#ifdef	__cplusplus
}
#endif

#endif	/* PIC24FV32KA302_H */

